var LiveServer = function(url, params)
{
    var callbacks = {};
    var ws_url = url;
    var conn;

    var self = this;

    if(typeof params === 'object'){
        params = $.param(params);
    }
    if(typeof params === 'string' && params.indexOf('=') > -1){
        if(ws_url.indexOf('?') > -1){
            ws_url += '&' + params;
        }else{
            ws_url += '?' + params;
        }
        url = ws_url;
    }

    this.bind = function(event_name, callback){
        callbacks[event_name] = callbacks[event_name] || [];
        callbacks[event_name].push(callback);
        return this;
    };

    this.addEventListener = function(type, listener, useCapture){
        if(typeof type === 'object'){
            for(var k in type){
                if(typeof type[k] === 'function'){
                    this.bind(k, type[k]);
                }
            }
        }else if(typeof type === 'string' && typeof listener === "function"){
            this.bind(type, listener);
        }
        return this;
    };

    this.send = function(event_data){
        console.log("send: " + event_data);
        this.conn.send( event_data );
        return this;
    };

    this.sendEvent = function(event_type, event_data){
        console.log("send: " + $.toJSON({event_type:event_type,event_data:event_data}));
        this.conn.send($.toJSON({event_type:event_type,event_data:event_data}));
        return this;
    };

    this.sendEventToUser = function(uid, event_type, event_data){
        this.sendEvent("__eventToUser",{toUid : uid, event_type : event_type, event_data : event_data});
        return this;
    };

    this.sendBroadcastToUser = function(uid, data){
        this.sendEvent("__broadcastToUser", {toUid:uid, event_data : data});
        return this;
    };

    this.connect = function() {
        if ( typeof(MozWebSocket) == 'function' )
            this.conn = new MozWebSocket(url);
        else
            this.conn = new WebSocket(url);

        // dispatch to the right handlers
        this.conn.onmessage = function(evt){
            if(self.isJSONString(evt.data)){
                var data = eval('('+evt.data+')');
                if(data.event_type){
                    dispatch(data.event_type, data.event_data)
                }else{
                    alert("错误的数据格式");
                }
            }else{
                dispatch('message', evt.data);
            }
        };

        this.conn.onclose = function(e){dispatch('close',e)};
        this.conn.onopen = function(e){dispatch('open',e)};
        this.conn.onerror = function(e){dispatch('error',e)};

        return this;
    };

    this.disconnect = function() {
        this.conn.close();
    };

    this.isJSONString = function(s){
        if(!s || s.length < 2)return false;
        return (s.charAt(0) == '{' || s.charAt(0) == '[') && (s.charAt(s.length - 1) == '}' || s.charAt(s.length - 1) == ']');
    };

    var dispatch = function(event_name, message){
        var chain = callbacks[event_name];
        if(typeof chain == 'undefined') {
            console.log('no "'+event_name+'" callbacks for this event');
            return; // no callbacks for this event
        }
        for(var i = 0; i < chain.length; i++){
            chain[i].call(self, message )
        }
    };
};